<template>
  <div ref="contextMenu">
    <slot></slot>
    <teleport to="body">
      <div
        v-if="showMenu"
        :style="{
          left: `${pos.posX}px`,
          top: `${pos.posY - 42}px`,
        }"
        class="context-menu"
      >
        <div v-resize="HandelResize" class="menu-list">
          <div v-for="item of menuList" class="menu-item" @click="HandelClick($event, item)">
            <i class="iconfont menu-icon" :class="[getMenuItemProp(item, 'icon')]"></i>
            <span class="menu-label"> {{ getMenuItemProp(item, "label") }}</span>
          </div>
        </div>
      </div>
    </teleport>
  </div>
</template>
<script setup lang="ts">
interface IResizeData {
  width: number;
  height: number;
}
import { computed, ref, nextTick } from "vue";
import { useContextMenu } from "@/hooks/useContextMenu.js";
import { useViewport } from "@/hooks/useViewport.js";
import { IBasicMenuItem } from "@/types/common";
const props = withDefaults(
  defineProps<{
    menuList: IBasicMenuItem[];
    content: any;
  }>(),
  {},
);
const w = ref(0);
const h = ref(0);
const contextMenu = ref(null);
const { vw, vh } = useViewport();
const { showMenu, x, y } = useContextMenu(contextMenu);
const emit = defineEmits(["select"]);
const pos = computed(() => {
  let posX = x.value;
  let posY = y.value + 40;
  if (x.value > vw.value - w.value) {
    posX -= w.value;
  }
  if (y.value + h.value > vh.value) {
    posY = vh.value - h.value;
  }
  return {
    posX,
    posY,
  };
});

const getMenuItemProp = (item: any, prop: "icon" | "label") => {
  return typeof item[prop] === "function" ? item[prop](props.content) : item[prop];
};

function HandelClick(event: MouseEvent, item: IBasicMenuItem) {
  nextTick(() => {
    showMenu.value = false;
    emit("select", event, item);
  });
}

function HandelResize({ width, height }: IResizeData) {
  w.value = width;
  h.value = height;
}
</script>
<style lang="scss" scoped>
.context-menu {
  position: fixed;
  background-color: var(--bg-context-menu);
  border-radius: 10px;
  min-width: 60px;
  padding: 5px 3px;
  cursor: pointer;
  box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
  .menu-list {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;

    .menu-item {
      padding: 5px 10px;
      width: 100%;
      display: flex;
      flex-direction: row;
      align-items: center;
      column-gap: 5px;
      border-radius: 5px;
      cursor: pointer;
      .menu-icon {
        font-size: 18px;
      }
      .menu-label {
        font-size: 13px;
        font-weight: 500;
      }
      &:hover {
        background-color: var(--bg-context-menu-hover);
        .menu-icon {
          animation: bounce-scale 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
        }
      }
    }
  }
}
</style>
